package com.common.response;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Result {

    /**
     * 请求成功，成功返回结果
     */
    public final static int SUCCESS = 1001;
    /**
     * 请求成功，返回失败的结果
     */
    public final static int FAIL = 1005;
    /**
     * 请求失败，返回不确定的未知结果
     */
    public final static int ERROR = 4001;

    /**
     * 后台未登录
     */
    public final static int NOT_LOGIN = 1000;

    /**
     * 微信未登录
     */
    public final static int WECHAT_NOT_LOGIN = 9001;

    @Data
    @Builder(builderClassName = "Builder")
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(value = JsonInclude.Include.NON_NULL)
    public static final class Res<T>{

        private Integer code;

        private String msg;

        private T datas;

    }

    public static Res successRes(Object object) {
        return Res.builder()
                .code(SUCCESS)
                .msg("请求成功~")
                .datas(object)
                .build();
    }

    public static com.alibaba.fastjson.JSONObject successObject(Object object) {
        com.alibaba.fastjson.JSONObject json = new com.alibaba.fastjson.JSONObject();
        json.put("code", SUCCESS);
        json.put("datas", object);
        json.put("msg", "请求成功~");
        return json;
    }

    public static String successObj(Object object) {
        JSONObject json = new JSONObject();
        json.element("code", SUCCESS);
        json.element("datas", object);
        json.element("msg", "请求成功~");
        return json.toString();
    }

    public static String successAliObj(Object object) {
        com.alibaba.fastjson.JSONObject json = new com.alibaba.fastjson.JSONObject();
        json.put("code", SUCCESS);
        json.put("datas", object);
        json.put("msg", "请求成功~");
        return json.toString();
    }

    public static String successAliObj(Object object,String msg) {
        com.alibaba.fastjson.JSONObject json = new com.alibaba.fastjson.JSONObject();
        json.put("code", SUCCESS);
        json.put("datas", object);
        json.put("msg", msg);
        return json.toString();
    }

    public static String successTokenObj(Object object, String token, Object menuObject, String[] excludes) {
        JSONObject json = new JSONObject();
        json.element("code", SUCCESS);
        JsonConfig config = initJsonConfig(excludes);
        json.element("datas", JSONObject.fromObject(object, config));
        json.element("token", token);
        json.element("userMenuAction", menuObject);
        json.element("msg", "请求成功~");
        return json.toString();
    }

    public static String successObj(Object object, String[] excludes) {
        JSONObject json = new JSONObject();
        json.element("code", SUCCESS);
        JsonConfig config = initJsonConfig(excludes);
        json.element("datas", JSONObject.fromObject(object, config));
        json.element("msg", "请求成功~");
        return json.toString();
    }

    public static String successArray(Object object, String[] excludes) {
        JSONObject json = new JSONObject();
        json.element("code", SUCCESS);
        JsonConfig config = initJsonConfig(excludes);
        json.element("datas", JSONArray.fromObject(object, config));
        json.element("msg", "请求成功~");
        return json.toString();
    }

    public static String successArray(long count, Object object) {
        JSONObject json = new JSONObject();
        json.element("code", SUCCESS);
        JsonConfig config = initJsonConfig(null);
        json.element("count", count);
        json.element("datas", object == null? new ArrayList() : JSONArray.fromObject(object, config));
        json.element("msg", "请求成功~");
        return json.toString();
    }

    public static String successArray(long count, List<?> objects,Object attach) {
        JSONObject json = new JSONObject();
        json.element("code", SUCCESS);
        JsonConfig config = initJsonConfig(null);
        json.element("count", count);
        json.element("datas", JSONArray.fromObject(objects,config));
        json.element("msg", "请求成功~");
        if(attach != null){
            json.element("attach",attach);
        }

        return json.toString();
    }

    public static String success() {
        JSONObject json = new JSONObject();
        json.element("code", SUCCESS);
        json.element("msg", "请求成功~");
        return json.toString();
    }

    public static String success(String msg) {
        JSONObject json = new JSONObject();
        json.element("code", SUCCESS);
        json.element("msg", msg);
        return json.toString();
    }

    public static String error(String msg) {
        JSONObject json = new JSONObject();
        json.element("code", FAIL);
        json.element("msg", msg == null ? "请求失败~" : msg);
        return json.toString();
    }

    public static JsonConfig initJsonConfig(String[] excludes) {
        JsonConfig config = new JsonConfig();
        String[] nomalExcludes = {"handler", "hibernateLazyInitializer"};
        if (excludes != null && excludes.length > 0) {
            nomalExcludes = mergeArray(nomalExcludes, excludes);
        }
        config.setExcludes(nomalExcludes);
        config.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
        config.registerJsonValueProcessor(Timestamp.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
        return config;
    }

    public static String[] mergeArray(String[] str1, String[] str2) {
        int strLen1 = str1.length;// 保存第一个数组长度
        int strLen2 = str2.length;// 保存第二个数组长度
        str1 = Arrays.copyOf(str1, strLen1 + strLen2);// 扩容
        System.arraycopy(str2, 0, str1, strLen1, strLen2);// 将第二个数组与第一个数组合并
        return str1;
    }
}
